package com.yupi.yoj.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yupi.yoj.common.ErrorCode;
import com.yupi.yoj.exception.BusinessException;
import com.yupi.yoj.exception.ThrowUtils;
import com.yupi.yoj.mapper.ContestMapper;
import com.yupi.yoj.model.entity.Contest;
import com.yupi.yoj.model.vo.ContestVO;
import com.yupi.yoj.service.ContestService;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.LocalDate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
* @author 46411
* @description 针对表【contest(竞赛)】的数据库操作Service实现
* @createDate 2024-10-05 01:13:37
*/
@Service
public class ContestServiceImpl extends ServiceImpl<ContestMapper, Contest>
implements ContestService{

    @Override
    public void validContest(Contest contest) {

        // 开始时间 至少在当前时间两个小时以后
        Date starttime = contest.getStarttime();
        Date date = new Date();
        if (starttime.before(new Date(date.getTime() + 2 * 60 * 60 * 1000))) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "开始时间至少在当前时间前两个小时以后");
        }

        // 内容可以为空
        String content = contest.getContent();
        // 标题不能为空
        String title = contest.getTitle();
        // 分数列表不能为空
        String tscores = contest.getTscores();
        // 题目id列表不能为空
        String tids = contest.getTids();
        if (StringUtils.isAnyBlank(tids, tscores, title)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }

        // 时间最长不能大于10且只能是0.5的整数倍
        Integer contestnum = contest.getContestnum();
        double pointPart = contestnum - (int)contestnum.doubleValue();
        ThrowUtils.throwIf(contestnum <= 0 || contestnum > 10 || pointPart > 0.5, ErrorCode.PARAMS_ERROR, "比赛时长必须大于0且小于等于10且只能是0.5的整数倍");

    }

    @Override
    public ContestVO getContestVO(Contest contest) {
        ContestVO contestVO = new ContestVO();
        BeanUtil.copyProperties(contest, contestVO);
        return contestVO;
    }

    @Override
    public List<ContestVO> getContestVO(List<Contest> contest) {
        LinkedList<ContestVO> contestVOS = new LinkedList<>();
        for (int i = 0; i < contest.size(); i++) {
            contestVOS.add(getContestVO(contest.get(i)));
        }
        return contestVOS;
    }

    @Override
    public List<Contest> getTwoCurrent() {
        QueryWrapper<Contest> contestQueryWrapper = new QueryWrapper<>();
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 计算时间差
        // 计算时间差，并进行排序
        contestQueryWrapper.orderByAsc("ABS(TIMESTAMPDIFF(SECOND, '" + now + "', starttime))");
        contestQueryWrapper.last("limit 2");
        return this.list(contestQueryWrapper);
    }

    @Override
    public List<Contest> getEndContest() {
        QueryWrapper<Contest> contestQueryWrapper = new QueryWrapper<>();
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 设置条件：starttime 小于当前时间
        contestQueryWrapper.lt("starttime", now);
        // 设置条件：starttime + contestnum小时 <= 当前时间
        contestQueryWrapper.and(wrapper ->
                wrapper.apply("DATE_ADD(starttime, INTERVAL contestnum HOUR) <= '" + now + "'")
        );
        return this.list(contestQueryWrapper);
    }
}
